import fs from 'fs'
import path from 'path'
import * as uuidins from 'uuid'
import crypto from 'crypto'

import {
  isArray,
  isBoolean,
  isNull,
  isNullOrUndefined,
  isNumber,
  isString,
  isSymbol,
  isUndefined,
  isRegExp,
  isObject,
  isDate,
  isError,
  isFunction,
  isPrimitive,
  isBuffer
} from 'core-util-is'

export {
  isArray,
  isBoolean,
  isNull,
  isNullOrUndefined,
  isNumber,
  isString,
  isSymbol,
  isUndefined,
  isRegExp,
  isObject,
  isDate,
  isError,
  isFunction,
  isPrimitive,
  isBuffer
}

//获得一个36的uuid字符串
export const uuid = (version) => {
  if (version === 'v1') return uuidins.v1();
  return uuidins.v4()
}

//对字符串进行md5加密
export const md5 = (str) => {
  return crypto.createHash('md5').update(str + '', 'utf8').digest('hex');
}

//延时
export const sleep = time => {
  return new Promise((resolve) => {
    setTimeout(resolve, time);
  });
}

/**
 * get datetime
 * @param  {Date} date []
 * @return {String}      []
 */
export function datetime(date = new Date(), format) {
  if (date && isString(date)) {
    const dateString = date;
    date = new Date(Date.parse(date));

    if (isNaN(date.getTime()) && !format) {
      format = dateString;
      date = new Date();
    }
  }
  format = format || 'YYYY-MM-DD HH:mm:ss';

  const fn = d => {
    return ('0' + d).slice(-2);
  };

  const d = new Date(date);
  const formats = {
    YYYY: d.getFullYear(),
    MM: fn(d.getMonth() + 1),
    DD: fn(d.getDate()),
    HH: fn(d.getHours()),
    mm: fn(d.getMinutes()),
    ss: fn(d.getSeconds())
  };

  return format.replace(/([a-z])\1+/ig, a => {
    return formats[a] || a;
  });
}


/**
 * get human readable file size
 * @param {Number/String} b file size
 * @param {Number} precision 
 */
export function humanSize(bytes, precision = 2) {
  const b = parseInt(bytes, 10)
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
  if (b === 0) { return '0 KB' }
  const i = parseInt(Math.floor(Math.log(b) / Math.log(1024)), 10)
  if (i === 0) { return `${b} ${sizes[i]}` }
  return `${(b / (1024 ** i)).toFixed(precision)} ${sizes[i]}`
}

/**
   * get human time
   * @param {Number} seconds 
   * @param {Object} param1 prefix/suffix
   * @returns 
   */
export function getHumanTime(seconds, params = { prefix : '', suffix : '' }) {
  let result = ''
  let hours = ''
  let minutes = ''
  let secs = seconds || 0
  const i = {
    gt1d: '> 1 day',
    hour: 'h',
    minute: 'm',
    second: 's'
  }

  if (secs <= 0) {
    return ''
  }
  if (secs > 86400) {
    return `${params.prefix}${i.gt1d}${params.suffix}`
  }
  if (secs > 3600) {
    hours = `${Math.floor(secs / 3600)}${i.hour} `
    secs %= 3600
  }
  if (secs > 60) {
    minutes = `${Math.floor(secs / 60)}${i.minute} `
    secs %= 60
  }
  secs += i.second
  result = hours + minutes + secs
  return result ? `${params.prefix}${result}${params.suffix}` : result
}

export const rs2ws = (rs, ws) => {
  return new Promise((resolve, reject) => {
    ws.on('close', () => {
      resolve();
    });
    rs.pipe(ws);
  });
}